package com.xxg.renrenuser.service;

import com.xxg.renrencommon.domain.bean.UserSpreadBenefitInfo;
import com.xxg.renrencommon.domain.constant.UserBenefitConstant;
import com.xxg.renrencommon.domain.dao.RenrenShopUser;
import com.xxg.renrencommon.domain.filedenum.userenum.BenefitStatusEnum;
import com.xxg.renrencommon.domain.filedenum.userenum.CashOutStatusEnum;
import com.xxg.renrencommon.domain.result.BaseResult;
import com.xxg.renrencommon.domain.result.PageInfoResult;
import com.xxg.renrencommon.exception.exceptionenum.UserExceptionCodeCodeEnum;
import com.xxg.renrenuser.dao.*;
import com.xxg.renrenuser.dao.bean.UserBankCardInfo;
import com.xxg.renrenuser.dao.bean.UserCashOutInfo;
import com.xxg.renrenuser.domain.query.CashOutQuery;
import com.xxg.renrenuser.domain.query.GetCashOutListQuery;
import com.xxg.renrenuser.domain.result.CountBenefitResult;
import com.xxg.renrenuser.domain.result.GetByStatusResult;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 类说明
 *
 * @author szj
 * @date 2021/12/21
 */
@Service
@Slf4j
@AllArgsConstructor
public class UserSpreadBenefitServiceImpl implements UserSpreadBenefitService{
    private final UserSpreadBenefitInfoDao userSpreadBenefitInfoDao;
    private final RenrenShopUserProfileDao renrenShopUserProfileDao;
    private final RenrenShopUserDao renrenShopUserDao;
    private final UserCashOutInfoDao userCashOutInfoDao;
    private final UserBankCardInfoDao userBankCardInfoDao;

    @Override
    public BaseResult<CountBenefitResult> countBenefit(String userIdStr) {
        Integer userId = Integer.parseInt(userIdStr);
        List<UserSpreadBenefitInfo> userSpreadBenefitInfos = userSpreadBenefitInfoDao.findByUserId(userId);
        BigDecimal unsettled = new BigDecimal("0");
        BigDecimal settled = new BigDecimal("0");
        BigDecimal revenue = new BigDecimal("0");
        if (userSpreadBenefitInfos != null) {
            for (UserSpreadBenefitInfo userSpreadBenefitInfo : userSpreadBenefitInfos) {
                if (BenefitStatusEnum.UNSETTLED.match(userSpreadBenefitInfo.getBenefitStatus())) {
                    unsettled = countTotal(unsettled, userSpreadBenefitInfo);
                }else if (BenefitStatusEnum.SETTLED.match(userSpreadBenefitInfo.getBenefitStatus())) {
                    settled = countTotal(settled, userSpreadBenefitInfo);
                }else {
                    revenue = countTotal(revenue, userSpreadBenefitInfo);
                }
            }
        }
        CountBenefitResult countBenefitResult = new CountBenefitResult();
        countBenefitResult.setUnsettled(unsettled);
        countBenefitResult.setSettled(settled);
        countBenefitResult.setRevenue(revenue);

        return new BaseResult<>(countBenefitResult);
    }

    @Override
    public BaseResult<List<GetByStatusResult>> getByStatus(Integer status, String userIdStr) {
        Integer userId = Integer.parseInt(userIdStr);
        List<UserSpreadBenefitInfo> userSpreadBenefitInfos = userSpreadBenefitInfoDao.findByUserIdAndStatus(userId, status);
        if (userSpreadBenefitInfos == null) {
            return new BaseResult<>();
        }
        Map<String, List<UserSpreadBenefitInfo>> collect = userSpreadBenefitInfos.stream().collect(Collectors.groupingBy(UserSpreadBenefitInfo::getOrderId));
        List<GetByStatusResult> getByStatusResults = new ArrayList<>(collect.size());
        collect.forEach((k, v) -> {
            GetByStatusResult getByStatusResult = new GetByStatusResult();
            getByStatusResult.setOrderId(k);
            BigDecimal profit = new BigDecimal("0");
            Date time = null;
            for (UserSpreadBenefitInfo userSpreadBenefitInfo : v) {
                profit = countTotal(profit, userSpreadBenefitInfo);
                if (!userSpreadBenefitInfo.getReFund()) {
                    time = userSpreadBenefitInfo.getOrderTime();
                }
            }
            getByStatusResult.setProfit(profit);
            getByStatusResult.setTime(time);

        });
        return new BaseResult<>(getByStatusResults);
    }

    @Override
    public BaseResult<Void> cashOut(String userIdStr, CashOutQuery query) {
        Integer userId = Integer.parseInt(userIdStr);
        List<String> orderIds = query.getOrderIds();
        List<UserSpreadBenefitInfo> userSpreadBenefitInfos = userSpreadBenefitInfoDao.findByUserIdAndOrderIdListAndStatus(userId, orderIds, BenefitStatusEnum.SETTLED.getValue());
        // 总提现金额大于500 小于 2万
        BigDecimal total = new BigDecimal("0");
        for (UserSpreadBenefitInfo userSpreadBenefitInfo : userSpreadBenefitInfos) {
            total = countTotal(total, userSpreadBenefitInfo);
        }
        if (total.compareTo(UserBenefitConstant.MIN) < 0 || total.compareTo(UserBenefitConstant.MAX) > 0) {
            return new BaseResult<>(UserExceptionCodeCodeEnum.CASH_OUT_AMOUNT_ERROR);
        }
        // 查看有没有未打款的提现记录，有则不支持
        UserCashOutInfo userCashOutInfo = userCashOutInfoDao.findByUserIdAndStatus(userId, CashOutStatusEnum.UN_DONE.getValue());
        if (userCashOutInfo != null) {
            return new BaseResult<>(UserExceptionCodeCodeEnum.HAS_UN_DONE_CASH_OUT);
        }
        String bindId = query.getBindId();
        UserBankCardInfo userBankCardInfo = userBankCardInfoDao.findByBindId(userIdStr, bindId);
        if (userBankCardInfo == null) {
            return new BaseResult<>(UserExceptionCodeCodeEnum.NOT_FIND_BANK_CARD);
        }
        RenrenShopUser renrenShopUser = renrenShopUserDao.selectByPrimaryKey(userId);
        RenrenShopUserProfile renrenShopUserProfile = renrenShopUserProfileDao.selectByPrimaryKey(userId);
        userCashOutInfo = new UserCashOutInfo();
        userCashOutInfo.setUserId(userId);
        if (renrenShopUserProfile != null) {
            userCashOutInfo.setNickname(renrenShopUserProfile.getNickname());
            userCashOutInfo.setUserPhoto(renrenShopUserProfile.getAvatar());
        }
        userCashOutInfo.setGroupId(renrenShopUser.getGroupId());
        userCashOutInfo.setUserName(userBankCardInfo.getUserName());
        userCashOutInfo.setCardNo(userBankCardInfo.getCardNo());
        userCashOutInfo.setBankName(userBankCardInfo.getBankName());
        userCashOutInfo.setOrderIds(orderIds);
        userCashOutInfo.setAmount(total.toString());
        userCashOutInfo.setUserSpreadBenefitInfos(userSpreadBenefitInfos);
        userCashOutInfo.setStatus(CashOutStatusEnum.UN_DONE.getValue());
        userCashOutInfoDao.insert(userCashOutInfo);
        return new BaseResult<>();
    }

    @Override
    public BaseResult<PageInfoResult<UserCashOutInfo>> getApplyList(GetCashOutListQuery query) {
        List<UserCashOutInfo> userCashOutInfos = userCashOutInfoDao.findByCondition(query);
        long total = userCashOutInfoDao.countByCondition(query);
        PageInfoResult<UserCashOutInfo> pageInfoResult = new PageInfoResult<>(total, userCashOutInfos);
        return new BaseResult<>(pageInfoResult);
    }

    @Override
    public BaseResult<Void> setApplyStatus(List<String> ids) {
        userCashOutInfoDao.setApplyStatus(ids);
        return new BaseResult<>();
    }

    private BigDecimal countTotal(BigDecimal total, UserSpreadBenefitInfo userSpreadBenefitInfo) {
        if (userSpreadBenefitInfo.getReFund()) {
            total = total.subtract(userSpreadBenefitInfo.getReturnPay());
        }else {
            total = total.add(userSpreadBenefitInfo.getProfit());
        }
        return total;
    }
}
